package com.netease.xone.widget;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.GridView;

import com.netease.xone.adapter.AdapterGridEmoticon;


public class ViewPagerChild extends GridView {
    /** 表情View被Click的监听 */
    private onEmoticonClickListener mListener;
    /** 表情View被Touch的监听 */
    private onEmoticonTouchListener mOnEmoticonTouchListener;
    /**
     * 存放表情符号和表情图片
     */
    private LinkedHashMap<String, Integer> mCurrentEmot;
    /**
     * 存放表情资源
     */
    private List<Emoticon> mFreData = new LinkedList<Emoticon>(); 
    /** 当前被选中的表情View */
    private View mPhraseView;

    private int mScrollStat;
    private AdapterGridEmoticon mAdapter;
    private Pop mPopScedule = new Pop();

    public ViewPagerChild(Context context) {
        super(context);
    }

    public ViewPagerChild(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ViewPagerChild(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    /**
     * 显示grid之前，必须先设置用的是哪套表情
     * 
     * @param map
     */
    public void setCurrentEmoticon(LinkedHashMap<String, Integer> map) {
        mCurrentEmot = map;
        Set<Entry<String, Integer>> set = mCurrentEmot.entrySet();
        mFreData.clear();
        Emoticon emoticon = null;
        for (Entry<String, Integer> entry : set) {
            emoticon = new Emoticon();
            emoticon.key = entry.getValue();
            emoticon.value = entry.getKey();
            mFreData.add(emoticon);
        }
    }
    
    /**
     * 显示之前的初始化
     */
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        if (mCurrentEmot == null)
            throw new IllegalStateException("you must set a emot map first");

        mAdapter = new AdapterGridEmoticon(getContext(), mFreData);
        setAdapter(mAdapter);
        setFocusable(false);
        setFocusableInTouchMode(false);

        setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                mScrollStat = scrollState;
                if (scrollState != OnScrollListener.SCROLL_STATE_IDLE
                        || mScrollStat == OnScrollListener.SCROLL_STATE_FLING) {
                    
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {

            }
        });

        try {
            Method method = getClass().getMethod("setOverScrollMode", int.class);
            if (method != null) {
                try {
                    method.invoke(this, 2);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int x = (int) ev.getX();
        int y = (int) ev.getY();
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mPopScedule.schedulePop(x, y);
            break;
        case MotionEvent.ACTION_MOVE:
            if (mPopScedule.isPoped()) {
                if (mScrollStat == OnScrollListener.SCROLL_STATE_IDLE
                        || mScrollStat == OnScrollListener.SCROLL_STATE_FLING) {
                    mPopScedule.PopPrompt(x, y);
                    return true;
                } else {
                    mPopScedule.unSchedulePop();
                }
            }
            break;
        case MotionEvent.ACTION_UP:
            if (mScrollStat == OnScrollListener.SCROLL_STATE_IDLE
                    || mScrollStat == OnScrollListener.SCROLL_STATE_FLING) {
                mPopScedule.setResult(x, y);
            }
            mPopScedule.unSchedulePop();
            break;
        }

        return super.onTouchEvent(ev);
    }
    
    /**
     * Touch表情View离开屏幕时产生的事件
     */
    protected void onEmoticonTouchUp() {
        if (mPhraseView == null)
            return;

        if (mOnEmoticonTouchListener != null)
            mOnEmoticonTouchListener.onClickUp((String) mPhraseView.getTag());

        mPhraseView = null;
    }

    /**
     * Touch表情View点击屏幕时产生的事件
     * 
     * @param view
     *            表情所在的View
     */
    protected void onEmoticonTouchDown(View view) {
        if (view == null)
            return;

        mPhraseView = view;

        if (mOnEmoticonTouchListener != null)
            mOnEmoticonTouchListener.onClickDown(view, (String) mPhraseView.getTag(), null);
    }
    
    
    /**
     * 处理表情View被Click
     * 
     * @param phrase
     */
    protected void onEmoticonClick(String phrase) {
        if (mListener != null)
            mListener.onClick(phrase);
    }
    
    
    /**
     * 设置表情View被Click的监听。<br>
     * Click和Touch的区别，见{@link EmoticonGrid}的注释
     * 
     * @param listener
     */
    public void setOnEmoticonClickListener(onEmoticonClickListener listener) {
        mListener = listener;
    }

    /**
     * 设置表情View被Touch的监听。<br>
     * Click和Touch的区别，见{@link EmoticonGrid}的注释
     * 
     * @param listener
     */
    public void setOnEmoticonTouchListener(onEmoticonTouchListener listener) {
        mOnEmoticonTouchListener = listener;
    }
    
    
    /**
     * 处理表情View的Touch。具体的效果可以由外部通过Listener指定。
     */
    private class Pop implements Runnable {
        private int scheduleX;
        private int scheduleY;
        private View oldChild; // 前一个表情View

        /**
         * 开始GridView中表情View的onTouch效果
         * 
         * @param x
         *            点击点的x坐标
         * @param y
         *            点击点的y坐标
         */
        public void schedulePop(int x, int y) {
            scheduleX = x;
            scheduleY = y;
            postDelayed(this, 500);
        }

        /**
         * 取消GridView中表情View的onTouch效果
         */
        public void unSchedulePop() {
            removeCallbacks(this);
            if (oldChild != null) {
                onEmoticonTouchUp();
                oldChild.setPressed(false);
            }
            oldChild = null;
        }

        public boolean isPoped() {
            return (oldChild != null);
        }

        @Override
        public void run() {
            if (mAdapter != null) {
                PopPrompt(scheduleX, scheduleY);
            }
        }

        /**
         * 处理GridView中格子（表情）的onTouch效果，包括touch聚焦以及产生事件（弹出文字放大镜，
         * 这个由外部传入的listener决定）。
         * 
         * @param x
         *            点击点的x坐标
         * @param y
         *            点击点的y坐标
         */
        public void PopPrompt(int x, int y) {
            if (mAdapter != null) {
                int position = pointToPosition(x, y);
                if (position == INVALID_POSITION)
                    return;

                int first = getFirstVisiblePosition();
                View child = getChildAt(position - first); // GridView中被点中的表情View。
                if (oldChild != child) {
                    onEmoticonTouchDown(child);
                    if (oldChild != null)
                        oldChild.setPressed(false);
                    if (child != null)
                        child.setPressed(true);
                }
                oldChild = child;
            }
        }

        /**
         * 记录表情的被点击时间，以便对表情排序。
         * 
         * @param x
         * @param y
         */
        public void setResult(int x, int y) {
            View v = oldChild;
            if (v == null) {
                int position = pointToPosition(x, y);
                if (position == INVALID_POSITION)
                    return;

                int first = getFirstVisiblePosition();
                v = getChildAt(position - first); // GridView中被点中的表情View。
            }

            if (v != null) {
                String phrase = (String) v.getTag();
                onEmoticonClick(phrase);
            }
        }

    }
    
    public static class Emoticon {
        // 存放表情题片
        public Integer key;
        // 保存表情符号
        public String  value;
    }
    /**
     * GridView中的表情View被Click的接口。<br>
     * Click和Touch的区别，见{@link EmoticonGrid}的注释
     */
    public interface onEmoticonClickListener {
        /**
         * GridView中的表情View被Click了。
         * 
         * @param phrase
         *            被点击的表情名称
         */
        public void onClick(String phrase);
    }

    /**
     * GridView中的表情View被Touch的接口。<br>
     * Click和Touch的区别，见{@link EmoticonGrid}的注释
     */
    public interface onEmoticonTouchListener {
        /**
         * GridView中的表情View被Touch时，处于up的状态，即抬起离开屏幕
         * 
         * @param phrase
         *            被点击的表情名称
         */
        public void onClickUp(String phrase);

        /**
         * GridView中的表情View被Touch时，处于down的状态，即点击屏幕
         * 
         * @param view
         *            被点击的表情View
         * @param phrase
         *            被点击的表情名称
         * @param title
         *            被点击的表情所属的类别
         */
        public void onClickDown(View view, String phrase, String title);
    }
}
